package com.broadsoft.platform.wfengine.runtime.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.broadsoft.platform.wfengine.DecisionType;
import com.broadsoft.platform.wfengine.EndNodeType;
import com.broadsoft.platform.wfengine.GeneralNodeType;
import com.broadsoft.platform.wfengine.JoinType;
import com.broadsoft.platform.wfengine.NodeType;
import com.broadsoft.platform.wfengine.SplitType;
import com.broadsoft.platform.wfengine.StartNodeType;
import com.broadsoft.platform.wfengine.SubflowType;
import com.broadsoft.platform.wfengine.runtime.NodeExecutionService;
import com.broadsoft.platform.wfengine.runtime.WfContext;
import com.broadsoft.platform.wfengine.runtime.nodehandler.INodeExecutionHandler;

/**
 * 
 * FIXME: <A few lines of description of what class is about and what it does.>
 * 
 * <HR/>
 * <B>Modification Block</B>
 * <P>
 * Version: FIXME: 1.0.1 <BR>
 * Author: FIXME: luzhen Date: 2011-9-15 TAG: <A short name to find out all changed made by this modification.>
 * Comments: Created. Bug fix NO.: <If required>
 * </P>
 * <P>
 * ... Other Modifications following above structure.
 * </P>
 * 
 */
public class NodeExecutionServiceImpl implements NodeExecutionService {

    private final static Logger logger = LoggerFactory.getLogger(NodeExecutionServiceImpl.class);
    
    private INodeExecutionHandler startNodeExecutionHandler;
    private INodeExecutionHandler endNodeExecutionHandler;
    private INodeExecutionHandler decisionNodeExecutionHandler;
    private INodeExecutionHandler generalNodeExecutionHandler;
    private INodeExecutionHandler splitNodeExecutionHandler;
    private INodeExecutionHandler joinNodeExecutionHandler;
    private INodeExecutionHandler subflowExecutionHandler;
    private INodeExecutionHandler externalNodeExecutionHandler;
    
    

    public NodeType executeStartNode(StartNodeType currentNode, WfContext flowContext) {
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeStartNode] begin");
        } 
        NodeType nextNode =startNodeExecutionHandler.executeNode(currentNode, flowContext);
        if (logger.isTraceEnabled()) { 
            logger.trace("The method[executeStartNode] end");
        }
        return nextNode ;
    }

    public NodeType executeEndNode(EndNodeType currentNode, WfContext flowContext) {
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeEndNode] begin");
        }
        NodeType nextNode = endNodeExecutionHandler.executeNode(currentNode, flowContext);
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeEndNode] end");
        }
        return nextNode ;
    }

    public NodeType executeGeneralNode(GeneralNodeType currentNode, WfContext flowContext) {
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeGeneralNode] begin");
        } 
        NodeType nextNode = generalNodeExecutionHandler.executeNode(currentNode, flowContext);
        if (logger.isTraceEnabled()) { 
            logger.trace("The method[executeGeneralNode] end");
        }
        return nextNode;
    }

    public NodeType executeDecisionNode(DecisionType currentNode, WfContext flowContext) {
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeConditionNode] begin");
        } 
        NodeType nextNodeType = decisionNodeExecutionHandler.executeNode(currentNode, flowContext);
        if (logger.isTraceEnabled()) { 
            logger.trace("The method[executeConditionNode] end");
        }
        return nextNodeType;
    }

    public NodeType executeSubflowNode(SubflowType currentNode, WfContext flowContext) {
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeChildFlowNode] begin");
        } 
        NodeType nextNodeType =subflowExecutionHandler.executeNode(currentNode, flowContext);
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeChildFlowNode] end");
        }
        return nextNodeType;
    }

    /**
     * 
     */
    public NodeType executeTimerNode(NodeType currentNode, WfContext flowContext) {
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeTimerNode] begin");
        }
        flowContext.setPreviousNode(currentNode);
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeTimerNode] end");
        }
        return null;
    }

    /**
     * 
     */
    public NodeType executeSplitNode(SplitType currentNode, WfContext flowContext) {
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeSplitNode] begin");
        }
        NodeType nextNodeType = splitNodeExecutionHandler.executeNode(currentNode, flowContext);

        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeSplitNode] end");
        }
        return nextNodeType;
    }

    public NodeType executeJoinNode(JoinType currentNode, WfContext flowContext) {
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeJoinNode] begin");
        }
        NodeType nextNodeType = joinNodeExecutionHandler.executeNode(currentNode, flowContext); 
        if (logger.isTraceEnabled()) { 
            logger.trace("The method[executeJoinNode] end");
        }
        return nextNodeType;
    }
    
    

    @Override
    public NodeType executeExternalNode(NodeType currentNode, WfContext flowContext) { 
        if (logger.isTraceEnabled()) {
            logger.trace("The method[executeExternalNode] begin");
        }
        NodeType nextNodeType = externalNodeExecutionHandler.executeNode(currentNode, flowContext);
        if (logger.isTraceEnabled()) { 
            logger.trace("The method[executeExternalNode] end");
        }
        return nextNodeType; 
    }
 
 

    // ==============

 

    
    public INodeExecutionHandler getStartNodeExecutionHandler() {
        return startNodeExecutionHandler;
    }

    public void setStartNodeExecutionHandler(INodeExecutionHandler startNodeExecutionHandler) {
        this.startNodeExecutionHandler = startNodeExecutionHandler;
    }

    public INodeExecutionHandler getEndNodeExecutionHandler() {
        return endNodeExecutionHandler;
    }

    public void setEndNodeExecutionHandler(INodeExecutionHandler endNodeExecutionHandler) {
        this.endNodeExecutionHandler = endNodeExecutionHandler;
    }

    public INodeExecutionHandler getDecisionNodeExecutionHandler() {
        return decisionNodeExecutionHandler;
    }

    public void setDecisionNodeExecutionHandler(INodeExecutionHandler decisionNodeExecutionHandler) {
        this.decisionNodeExecutionHandler = decisionNodeExecutionHandler;
    }

    public INodeExecutionHandler getGeneralNodeExecutionHandler() {
        return generalNodeExecutionHandler;
    }

    public void setGeneralNodeExecutionHandler(INodeExecutionHandler generalNodeExecutionHandler) {
        this.generalNodeExecutionHandler = generalNodeExecutionHandler;
    }

    public INodeExecutionHandler getSplitNodeExecutionHandler() {
        return splitNodeExecutionHandler;
    }

    public void setSplitNodeExecutionHandler(INodeExecutionHandler splitNodeExecutionHandler) {
        this.splitNodeExecutionHandler = splitNodeExecutionHandler;
    }

    public INodeExecutionHandler getJoinNodeExecutionHandler() {
        return joinNodeExecutionHandler;
    }

    public void setJoinNodeExecutionHandler(INodeExecutionHandler joinNodeExecutionHandler) {
        this.joinNodeExecutionHandler = joinNodeExecutionHandler;
    }

    public INodeExecutionHandler getSubflowExecutionHandler() {
        return subflowExecutionHandler;
    }

    public void setSubflowExecutionHandler(INodeExecutionHandler subflowExecutionHandler) {
        this.subflowExecutionHandler = subflowExecutionHandler;
    }

    public INodeExecutionHandler getExternalNodeExecutionHandler() {
        return externalNodeExecutionHandler;
    }

    public void setExternalNodeExecutionHandler(INodeExecutionHandler externalNodeExecutionHandler) {
        this.externalNodeExecutionHandler = externalNodeExecutionHandler;
    }

    
    
    

}
